package com.huacloud.qw.mysql.shell.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.shell.standard.ShellComponent;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import static org.springframework.jdbc.support.JdbcUtils.closeConnection;
/**
 * @author zhaoqiankun
 * Date on 2021/7/15  9:05
 * descriptio mysql的工具类
 */
@Slf4j
@Configuration
@ShellComponent
public class DBMysqlUtil {

    /**
     *数据库连接会话
     */
    private Connection conn = null;
    /**
     *编译 SQL 语句的对象
     */
    private PreparedStatement ps = null;
    /**
     *用于执行静态 SQL 语句并返回它产生的结果的对象。
     */
    private Statement statement = null;
    /**
     *结果集列
     */
    private ResultSet rs = null;
    /**
     *数据库驱动
     */
    private final String dbDriver;
    /**
     *数据库连接url
     */
    private String dbConnectionUrl;
    /**
     *数据库用户
     */
    private  final String Username;
    /**
     *数据库密码
     */
    private  final  String dbPassword;
    /**
     * 查询表的
     */
    private static final String SQL = "SELECT * FROM ";


    /**
     * 无参构造器
     */
    public DBMysqlUtil() {
        this.dbDriver = null;
        this.dbConnectionUrl = null;
        this.Username = null;
        this.dbPassword = null;
    }

    /**
     * 有参构造器
     */
    public DBMysqlUtil(String dbDriver, String dbConnectionUrl, String userName, String dbPassword) {
        this.dbDriver = dbDriver;
        this.dbConnectionUrl = dbConnectionUrl;
        this.Username = userName;
        this.dbPassword = dbPassword;
    }


    /**
     * 功能：获取数据库连接
     * @return  数据库连接
     */

    public Connection getConnection() {
        log.info("连接地址：" + dbConnectionUrl);
        log.info("用户名：" + Username);
        log.info("密码：" + dbPassword);
        log.info("连接地址：" + dbConnectionUrl);
        try {
            Class.forName(dbDriver);
            //到连接源哪里，没有到数据
            DriverManager.setLoginTimeout(2);
            conn = DriverManager.getConnection(dbConnectionUrl, Username,
                    dbPassword);
            if (dbConnectionUrl != null && dbDriver != null && Username != null && dbPassword != null) {
                log.info("数据库连接成功");
            } else {
                log.info("请先连接数据！");
                return null;
            }
        } catch (Exception e) {
            throw  new RuntimeException("Error: DbUtil.getConnection() 获得数据库链接失败.\r\n链接类型:"
                    + dbDriver + "\r\n链接URL:" + dbConnectionUrl + "\r\n链接用户:"
                    + Username + "\r\n链接密码:" + dbPassword + e + "请检查数据库连接");
        }
        return conn;
    }

    /**
     * 指定数据库
     */
    public Connection selectDataBase(String databaseName) {
        log.info("选择的数据库名字：" + databaseName);

        try {
            Class.forName(dbDriver);
            //到连接源哪里，没有到数据
            //数据库后面？的索引
            //返回此字符串中第一次出现指定子字符串的索引，从指定索引开始
            int i = dbConnectionUrl.indexOf("/",23);
            String databaseIndexBefore  = dbConnectionUrl.substring(0, i+1);
            log.info(databaseIndexBefore);
            int i1 = dbConnectionUrl.indexOf("?",27);
            String databaseIndexLater = dbConnectionUrl.substring(i1);
            log.info(databaseIndexLater);
            dbConnectionUrl = databaseIndexBefore + databaseName+ databaseIndexLater;
            log.info(dbConnectionUrl);
            conn = DriverManager.getConnection(dbConnectionUrl, Username,
                    dbPassword);
            //jdbc:mysql://172.16.123.18:3306mysqmysql?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
            //"jdbc:mysql://"+ ip + ":" +port +"/" + "?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC";
            //"jdbc:mysql://localhost:3306/mybase?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC"
            if (dbConnectionUrl != null && dbDriver != null && Username != null && dbPassword != null) {
                log.info("数据库连接成功");
            } else {
                log.info("请先连接数据！");
            }
        } catch (Exception e) {
            throw  new RuntimeException("Error: DbUtil.getConnection() 获得数据库链接失败.\r\n链接类型:"
                    + dbDriver + "\r\n链接URL:" + dbConnectionUrl + "\r\n链接用户:"
                    + Username + "\r\n链接密码:" + dbPassword + e + "请检查数据库连接");
        }
        return conn;
    }



    /**
     * 功能：执行查询语句
     * @param sql  语句
     * @return 结果集列
     */
    public ResultSet select(String sql) {
        log.info("Exec select sql:" + sql);
        try {
            conn = getConnection();
            statement = conn.createStatement();
            rs = statement.executeQuery(sql);
        } catch (Exception e) {
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return rs;

    }





    /**
     * 功能：执行查询语句，获取记录数
     * @param sql 语句
     * @return  获取记录数
     */
    public Object getRecordCount(String sql) {
        log.info("Exec getRecordCount sql:" + sql);
        int counter = 0;
        try {
            conn = getConnection();
            ps = conn.prepareStatement(sql);
            if (conn == null) {
                return "请先连接数据库";
            }
            rs = ps.executeQuery(sql);
            while (rs.next()) {
                counter++;
            }
        } catch (SQLException e) {
            log.error("执行DbUtil.getRecordCount()方法发生异常，异常信息：" + e);
        } finally {
            close();
        }
        log.info("counter总数：" + counter);
        return counter;
    }


    /**
     * 功能:针对单条记录执行更新操作(新增、修改、删除)
     * @param sql 语句
     * @return num 影响条数
     */
    public int executeupdate(String sql) {
        log.info("Exec update sql:" + sql);
        int num;
        try {
            conn = getConnection();
            if (conn == null) {
                log.info("你没没有连接请先连接数据库 执行connect方法连接");
                return 0;
            }
            ps = conn.prepareStatement(sql);
            num = ps.executeUpdate();
        } catch (SQLException sqle) {
            throw  new RuntimeException("insert/update/delete  data Exception: " +
                    sqle.getMessage());
        } finally {
            close();
        }
        log.info("影响条数：" + num);
        return num;
    }

    /**
     * 功能:批量执行SQL(update或delete)
     * @param sqlList sql语句集合
     * @return 执行次数
     */
    public int executeBatch(List<String> sqlList) {
        int result = 0;
        for (String sql : sqlList) {
            try {
                result += executeupdate(sql);
            } catch (Exception e) {
                log.error("查询异常：" + e.getMessage());
            }
        }
        log.info("executeBatch Result:" + result);
        return result;
    }


    /**
     * 所有增删改
     * @param sql 语句
     * @return  字符串成功
     */
    public String createTable(String sql,String databaseName) {
        log.info("Exec select sql:" + sql);
        try {
            conn = selectDataBase(databaseName);
            statement = conn.createStatement();
            statement.execute(sql);
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return "返回成功";
    }

    /**
     * 所有查询操作
     * @param sql 语句
     * @return 结果集
     */
    public ResultSet allSelect(String sql,String databaseName) {
        log.info("Exec select sql:" + sql);
        try {
            conn = selectDataBase(databaseName);
            statement = conn.createStatement();
            rs = statement.executeQuery(sql);
            ResultSetMetaData rsMetaData = rs.getMetaData();
            int size = rsMetaData.getColumnCount();
            //数据库字段名
            List<String> cloumnList = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                cloumnList.add(rsMetaData.getColumnName(i + 1));
            }
            log.info("数据库字段名" + cloumnList);
            while (rs.next()) {
                for (int i = 0; i < size; i++) {
                    log.info(rs.getString(i+1)+"\t");
                }
                log.info("\n");
            }
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return rs;
    }


    /**
     * 查询建表语句
     * @param tableName 表名
     * @return sql结果集列
     */
    public ResultSet createTableDdl(String tableName,String databaseName) {
        log.info("Exec select sql:" + tableName);
        try {
            conn = selectDataBase(databaseName);
            statement = conn.createStatement();
            String sql = "show create table " + tableName;
            rs = statement.executeQuery(sql);
            String createSql;
            log.info("以下是建表语句");
            while (rs.next()) {
                BufferedReader br = new BufferedReader(new InputStreamReader(rs.getAsciiStream(rs.getMetaData().getColumnCount()), "UTF-8"));
                while ((createSql = br.readLine()) != null) {
                    log.info(createSql);
                }
            }
            log.info(rs.toString());
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return rs;
    }


    /**
     * 查看表中所有字段
     * @param tableName 表名
     * @return 表的所有字段
     */
    public List<String> getColumnNames(String tableName,String databaseName) {
        List<String> columnNames = new ArrayList<>();
        //与数据库的连接
        conn = getConnection();
        Connection conn = getConnection();
        String tableSql = SQL + tableName;
        try {
            ps = conn.prepareStatement(tableSql);
            //结果集元数据
            ResultSetMetaData rsmd = ps.getMetaData();
            //表列数
            int size = rsmd.getColumnCount();
            for (int i = 0; i < size; i++) {
                columnNames.add(rsmd.getColumnName(i + 1));
            }
            log.info("下面为表的所有字段"+ "\n");
            log.info(columnNames.toString());
        } catch (SQLException e) {
            throw  new RuntimeException("getColumnNames failure", e);
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    closeConnection(conn);
                } catch (SQLException e) {
                    throw  new RuntimeException("getColumnNames close pstem and connection failure", e);
                }
            }
        }
        return columnNames;
    }

    /**
     * 功能:关闭数据库的连接
     */
    public void close() {
        try {
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
            if (conn != null) {
                conn.close();
            }
            log.info("关闭数据库连接成功");
        } catch (Exception e) {
            throw  new RuntimeException("执行DbUtil.close()方法发生异常，异常信息：", e);
        }
    }


    /**
     * 查看数据库版本
     * @return  数据库版本
     */
    public ResultSet mysqlVersion() {
        try {
            conn = getConnection();
            statement = conn.createStatement();
            String sql = "select version() ";
            rs = statement.executeQuery(sql);
            String createSql;
            log.info("以下是数据库版本"+"\n");
            while (rs.next()) {
                BufferedReader br = new BufferedReader(new InputStreamReader(rs.getAsciiStream(rs.getMetaData().getColumnCount()),"GBK"));
                while ((createSql = br.readLine()) != null) {
                    log.info(createSql);
                }
            }
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return rs;
    }

    /**
     * 获取表中所有字段类型
     * @param tableName   表名
     * @return 表中所有字段类型
     */
    public List<String> getColumnTypes(String tableName,String databaseName) {
        List<String> columnTypes = new ArrayList<>();
        //与数据库的连接
        conn = getConnection();
        String tableSql = SQL + tableName;
        try {
            ps = conn.prepareStatement(tableSql);
            //结果集元数据
            ResultSetMetaData rsmd = ps.getMetaData();
            //表列数
            int size = rsmd.getColumnCount();
            for (int i = 0; i < size; i++) {
                columnTypes.add(rsmd.getColumnTypeName(i + 1));
            }
            log.info("获取表中所有字段类型" + columnTypes);
        } catch (SQLException e) {
            throw  new RuntimeException("getColumnTypes failure", e);
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                    closeConnection(conn);
                } catch (SQLException e) {
                    throw  new RuntimeException("getColumnTypes close pstem and connection failure", e);
                }
            }
        }
        return columnTypes;
    }




    /**
     * 获取表中字段的所有注释
     * @param tableName 表名
     * @return 表中字段的所有注释
     */
    public List<String> getColumnComments(String tableName,String databaseName) {
        //与数据库的连接
        conn = getConnection();
        //列名注释集合
        List<String> columnComments = new ArrayList<>();
        String tableSql = SQL + tableName;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(tableSql);
            rs = ps.executeQuery("show full columns from " + tableName);
            while (rs.next()) {
                columnComments.add(rs.getString("Comment"));
            }
            log.info(columnComments.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                    closeConnection(conn);
                } catch (SQLException e) {
                    log.error("getColumnComments close ResultSet and connection failure", e);
                }
            }
        }
        return columnComments;
    }


    /**
     * 获得一个表的索引信息
     * @param tableName  表名
     */
    public void getIndexInfo(String tableName,String databaseName) {
        try {
            List<String> columnNames = new ArrayList<>();
            List<String> columnNames2 = new ArrayList<>();
            conn = getConnection();
            statement = conn.createStatement();
            String sql = "SHOW INDEX FROM  " + tableName;
            rs = statement.executeQuery(sql);
            String createSql = null;
            log.info("以下是表的索引信息" + "\n");
            ResultSetMetaData rsMetaData = rs.getMetaData();
            int size = rsMetaData.getColumnCount();
            for (int i = 0; i < size; i++) {
                columnNames.add(rsMetaData.getColumnName(i + 1));
            }
            log.info(columnNames.toString());
            while (rs.next()) {
                for (int i = 0; i < size; i++) {
                    columnNames2.add(rs.getString(i + 1));
                }
                log.info(columnNames2.toString());
            }
        } catch (Exception e) {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }


    /**
     * 获取数据库一些信息
     */
    public void getDataBaseInformations()
    {
        try
        {
            conn = getConnection();
            statement = conn.createStatement();
            DatabaseMetaData dbMetaData = getMetaData();
            log.info("下面是数据库的相关信息\n");
            log.info("URL:" + dbMetaData.getURL() + ";");
            log.info("UserName:" + dbMetaData.getUserName() + ";");
            log.info("isReadOnly:" + dbMetaData.isReadOnly() + ";");
            log.info("DatabaseProductName:" + dbMetaData.getDatabaseProductName() + ";");
            log.info("DatabaseProductVersion:" + dbMetaData.getDatabaseProductVersion() + ";");
            log.info("dbDriverName:" + dbMetaData.getDriverName() + ";");
            log.info("dbDriverVersion:" + dbMetaData.getDriverVersion());
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }
    /**
     * 获得数据库中所有方案名称
     */
    public void getAllSchemas()
    {
        try
        {
            DatabaseMetaData dbMetaData = getMetaData();
            ResultSet rs = dbMetaData.getSchemas();
            while (rs.next())
            {
                String tableSchem = rs.getString("TABLE_SCHEM");
                log.info("tableSchem为：" +tableSchem);
            }
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }

    /**
     * @return  返回 连接数据库的元数据
     * @throws SQLException sql异常
     */
    private DatabaseMetaData getMetaData() throws SQLException {
        return getConnection().getMetaData();
    }

    /**
     * 获得表或视图中的所有列信息
     * @param tableName 表名
     */
    public void getTableColumns(String tableName,String databaseName)
    {
        try
        {
            DatabaseMetaData dbMetaData = getMetaData();
            ResultSet rs = dbMetaData.getColumns(null, dbMetaData.getDatabaseProductName(), tableName, "%");
            while (rs.next())
            {
                // table catalog (may be null)
                String tableCat = rs.getString("TABLE_CAT");
                // table schema (may be null)
                String tableSchemaName = rs.getString("TABLE_SCHEM");
                // table name
                String tableNameColumnLabel = rs.getString("TABLE_NAME");
                // column name
                String columnName = rs.getString("COLUMN_NAME");
                // SQL type from java.sql.Types
                int dataType = rs.getInt("DATA_TYPE");
                // Data source dependent type name, for a UDT the type name is
                // fully qualified
                String dataTypeName = rs.getString("TYPE_NAME");
                // table schema (may be null)
                int columnSize = rs.getInt("COLUMN_SIZE");
                // the number of fractional digits. Null is returned for data
                // types where DECIMAL_DIGITS is not applicable.
                int decimalDigits = rs.getInt("DECIMAL_DIGITS");
                // Radix (typically either 10 or 2)
                int numPrecRadix = rs.getInt("NUM_PREC_RADIX");
                // is NULL allowed.
                int nullAble = rs.getInt("NULLABLE");
                // comment describing column (may be null)
                String remarks = rs.getString("REMARKS");
                // default value for the column, which should be interpreted as
                // a string when the value is enclosed in single quotes (may be
                // null)
                String columnDef = rs.getString("COLUMN_DEF");
                //
                int sqlDataType = rs.getInt("SQL_DATA_TYPE");
                //
                int sqlDatetimeSub = rs.getInt("SQL_DATETIME_SUB");
                // for char types the maximum number of bytes in the column
                int charOctetLength = rs.getInt("CHAR_OCTET_LENGTH");
                // index of column in table (starting at 1)
                int ordinalPosition = rs.getInt("ORDINAL_POSITION");
                // ISO rules are used to determine the nullability for a column.
                // YES --- if the parameter can include NULLs;
                // NO --- if the parameter cannot include NULLs
                // empty string --- if the nullability for the parameter is
                // unknown
                String isNullAble = rs.getString("IS_NULLABLE");
                // Indicates whether this column is auto incremented
                // YES --- if the column is auto incremented
                // NO --- if the column is not auto incremented
                // empty string --- if it cannot be determined whether the
                // column is auto incremented parameter is unknown
                String isAutoincrement = rs.getString("IS_AUTOINCREMENT");
                log.info("tableCat : " + tableCat +
                        " - " + "tableSchemaName : " + tableSchemaName +
                        " - " + "tableNameColumnLabel : " + tableNameColumnLabel +
                        " - " + "columnName : " +columnName +
                        " - " + "dataType : " + dataType +
                        " - " +"dataTypeName : " + dataTypeName +
                        " - " + "columnSize :" + columnSize +
                        " - " + "decimalDigits : " +  decimalDigits +
                        " numPrecRadix : " + "-" + numPrecRadix +
                        " nullAble : " + "-" + nullAble +
                        " remarks : " + "-" + remarks +
                        " columnDef : " + "-" + columnDef +
                        " sqlDataType : " + "-" + sqlDataType +
                        " sqlDatetimeSub : " + "-" + sqlDatetimeSub +
                        " charOctetLength : " + "-" + charOctetLength +
                        " ordinalPosition : " + "-" + ordinalPosition +
                        " isNullAble : " + "-" + isNullAble +
                        " isAutoincrement : " + "-" + isAutoincrement + "-");
            }
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }

    /**
     * 获得该用户下面的所有视图
     * @param schemaName 数据库名
     */
    public void getAllViewList(String schemaName)
    {
        try
        {
            DatabaseMetaData dbMetaData = getMetaData();
            String[] types =
                    { "VIEW" };
            ResultSet rs = dbMetaData.getTables(null, schemaName, "%", types);
            log.info("下面输出该用户下面的所有视图");
            while (rs.next())
            {
                String viewName = rs.getString("TABLE_NAME");
                String viewType = rs.getString("TABLE_TYPE");
                // 表上的解释性评论
                String remarks = rs.getString("REMARKS");
                log.info("这是视图相关信息： " + viewName + "  -  "   + viewType + " -  " + remarks);
            }
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }


    /**
     *获得一个表的主键信息
     * @param schemaName  表名
     * @param tableName   数据库名
     */
    public void getAllPrimaryKeys(String schemaName, String tableName)
    {
        try
        {
            DatabaseMetaData dbMetaData = getMetaData(schemaName);
            ResultSet rs = dbMetaData.getPrimaryKeys(null, schemaName, tableName);
            if (!rs.next()) {
                log.info("没有主键信息");
            }
            while (rs.next())
            {
                // column name
                String columnName = rs.getString("COLUMN_NAME");
                // sequence number within primary key( a value of 1 represents
                // the first column of the primary key, a value of 2 would
                // represent the second column within the primary key).
                short keySeq = rs.getShort("KEY_SEQ");
                // primary key name (may be null)
                String pkName = rs.getString("PK_NAME");
                log.info("字段名： " + columnName + " -主键内序列号： " + keySeq + " - 主键名称： " + pkName);
            }
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }

    /**
     *  获得一个表的外键信息
     * @param schemaName  表名
     * @param tableName   数据库名
     */
    public void getAllExportedKeys(String schemaName, String tableName)
    {
        try
        {
            DatabaseMetaData dbMetaData = getMetaData(schemaName);
            ResultSet rs = dbMetaData.getExportedKeys(null, schemaName, tableName);
            if (!rs.next()) {
                log.info("该表没有外键信息");
            }
            while (rs.next())
            {
                // primary key table catalog (may be null)
                String pkTableCat = rs.getString("PKTABLE_CAT");
                // primary key table schema (may be null)
                String pkTableSchem = rs.getString("PKTABLE_SCHEM");
                // primary key table name
                String pktableName = rs.getString("PKTABLE_NAME");
                // primary key column name
                String pkColumnName = rs.getString("PKCOLUMN_NAME");
                // foreign key table catalog (may be null) being exported (may
                // be null)
                String fkTableCat = rs.getString("FKTABLE_CAT");
                // foreign key table schema (may be null) being exported (may be
                // null)
                String fkTableSchem = rs.getString("FKTABLE_SCHEM");
                // foreign key table name being exported
                String fktableName = rs.getString("FKTABLE_NAME");
                // foreign key column name being exported
                String fkColumnName = rs.getString("FKCOLUMN_NAME");
                // sequence number within foreign key( a value of 1 represents
                // the first column of the foreign key, a value of 2 would
                // represent the second column within the foreign key).
                short keySeq = rs.getShort("KEY_SEQ");
                // What happens to foreign key when primary is updated:
                // importedNoAction - do not allow update of primary key if it
                // has been imported
                // importedKeyCascade - change imported key to agree with
                // primary key update
                // importedKeySetNull - change imported key to NULL if its
                // primary key has been updated
                // importedKeySetDefault - change imported key to default values
                // if its primary key has been updated
                // importedKeyRestrict - same as importedKeyNoAction (for ODBC
                // 2.x compatibility)
                short updateRule = rs.getShort("UPDATE_RULE");
                short delRule = rs.getShort("DELETE_RULE");
                // foreign key name (may be null)
                String fkName = rs.getString("FK_NAME");
                // primary key name (may be null)
                String pkName = rs.getString("PK_NAME");
                short deferRability = rs.getShort("DEFERRABILITY");
                log.info(pkTableCat + "-" + pkTableSchem + "-" + pktableName + "-" + pkColumnName + "-"
                        + fkTableCat + "-" + fkTableSchem + "-" + fktableName + "-" + fkColumnName + "-" + keySeq + "-"
                        + updateRule + "-" + delRule + "-" + fkName + "-" + pkName + "-" + deferRability);
            }
        } catch (SQLException e)
        {
            // TODO: handle SQLException
            e.printStackTrace();
        }
    }

    /**
     * 返回带指定数据库的数据元
     * @param schemaName 表名
     * @return  返回带指定数据库的数据元
     * @throws SQLException sql异常
     */
    private DatabaseMetaData getMetaData(String schemaName) throws SQLException {
        return selectDataBase(schemaName).getMetaData();
    }


    /**
     * 查看表结构
     * @param tableName 表名
     * @return  结果集
     */
    public ResultSet describeTable(String tableName,String databaseName) {
        try {
            conn = selectDataBase(databaseName);
            statement = conn.createStatement();
            String sql = " describe " + tableName;
            rs = statement.executeQuery(sql);
            String createSql;
            log.info("查看表结构");
            while (rs.next()) {
                BufferedReader br = new BufferedReader(new InputStreamReader(rs.getAsciiStream(rs.getMetaData().getColumnCount()),"GBK"));
                while ((createSql = br.readLine()) != null) {
                    log.info(createSql);
                }
            }
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return rs;
    }


    /**
     * 创建数据库
     * @param databaseName 数据库名
     * @return 成功
     */
    public String createDatabase(String databaseName) {
        String sql = "CREATE DATABASE `"+databaseName+"` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';";
        log.info("Exec select sql:" + sql);
        try {
            conn = getConnection();
            statement = conn.createStatement();
            statement.execute(sql);
        } catch (Exception e) {
            //：如果你的SQL 语句是诸如update,insert的更新语句，应该用statement的execute()方法，
            // 如果用的是statement的executeQuery()就会出现上诉问题
            throw  new RuntimeException("查询数据异常:" + e.getMessage());
        }
        return "返回成功";
    }


}
